/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, Hardware
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "texture_layer.h"

#include "include/gpu/GrContext.h"
#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/gl/GrGLInterface.h"

namespace OHOS {
namespace Render3D {
TextureLayer::~TextureLayer()
{
    image_.skImage_ = nullptr;
}

SkRect TextureLayer::onGetBounds()
{
    return SkRect::MakeWH(image_.textureInfo_.width_, image_.textureInfo_.height_);
}

void TextureLayer::onDraw(SkCanvas* canvas)
{
    std::lock_guard<std::mutex> lk(ftrMut_);
    if (image_.ftr_.valid()) {
        image_.ftr_.get();
        DrawTexture(canvas);
    }
}

void TextureLayer::UpdateAsyncTexImage(std::shared_future<void> ftr, const TextureInfo info,
    int32_t offsetX, int32_t offsetY)
{
    std::lock_guard<std::mutex> lk(ftrMut_);
    image_.ftr_ = ftr;
    image_.textureInfo_ = info;
    offsetX_ = offsetX;
    offsetY_ = offsetY;
}

std::shared_future<void> TextureLayer::UpdateSyncTexImage(const std::function<EngineService::EngineTask>& task)
{
    std::promise<void> p;
    image_.pms_.swap(p);
    image_.ftr_ = image_.pms_.get_future();
    image_.task_ = std::move(task);
    return image_.ftr_;
}

void TextureLayer::DrawTexture(SkCanvas* canvas)
{
    if (image_.textureInfo_.textureId_ <= 0) {
        return;
    }

    if (image_.skImage_ != nullptr) {
        GrGLTextureInfo textureInfo = { GL_TEXTURE_2D, image_.textureInfo_.textureId_, GL_RGBA8_OES };
        GrBackendTexture backendTexture(image_.textureInfo_.width_, image_.textureInfo_.height_,
            GrMipMapped::kNo, textureInfo);

        image_.skImage_ = SkImage::MakeFromTexture(canvas->getGrContext(), backendTexture, kTopLeft_GrSurfaceOrigin,
            kRGBA_8888_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB());
    }

    canvas->drawImage(image_.skImage_, offsetX_, offsetY_);
}
}
}